#include <iostream>
#include "MyString.h"
using namespace std;

void Strcpy(char* destination, const char* source)
{
	//字符串拷贝函数，不属于类
	int i = 0;
	for (; source[i]; i++)
	{
		destination[i] = source[i];
	}
	destination[i] = 0;
}
int Strlen(const char* source)
{
	//计算字符串长度，不属于类
	int i = 0;
	while (source[i])
		++i;
	return i;
}

MyString::MyString(/* args */)
{
	num_of_s = 0;
	size = 100;
	expansion = 100;
	s = Expand(100);
	s[0] = 0;
}
MyString::MyString(const char& in)
{
	num_of_s = 1;
	expansion = 100;
	size = 0;
	s = Expand(num_of_s);
	s[0] = in;
	s[1] = 0;
}
MyString::MyString(const char* in)
{
	num_of_s = 0;
	expansion = 100;
	size = 0;
	s = NULL;
	this->ConstructWithChar(in);
}
MyString::MyString(const MyString& str)
{
	num_of_s = str.num_of_s;
	size = str.size;
	expansion = str.expansion;
	s = new char[size];
	Strcpy(s, str.s);
}
MyString::~MyString()
{
	if (s)
		delete[] s;
	s = NULL;
}
void MyString::ConstructWithChar(const char* in)
{
	num_of_s = Strlen(in);
	expansion = 100;
	size = 0;
	s = Expand(num_of_s);
	Strcpy(s, in);
}

MyString& MyString::operator=(const char* in)
{
	if (this->s)
	{
		delete[] s;
		s = NULL;
	}
	ConstructWithChar(in);
	return *this;
}
MyString& MyString::operator=(const MyString& source)
{
	if (this->s)
	{
		delete[] s;
		s = NULL;
	}
	ConstructWithChar(source.s);
	return *this;
}
char MyString::operator[](const int& index)
{
	if (index < num_of_s)
		return this->s[index];
	return 0;
}


ostream& operator<<(ostream& out, const MyString& str)
{
	for (int i = 0; i < str.num_of_s; i++)
	{
		out << str.s[i];
	}
	return out;
}

istream& operator>>(istream& in, MyString& str)
{
	char buffer[1024];
	char tmp = 0;
	int i = 0;
	while (true)
	{
		tmp = getchar();
		if (tmp == '\n') break;
		buffer[i++] = tmp;
	}
	buffer[i] = 0;
	str.ConstructWithChar(buffer);

	return in;
}

char* MyString::Expand(int need_space)
{
	expansion *= 2;//拓展一次增大一次，避免多次调用拓展函数
	while (expansion + size < need_space)
		expansion *= 2;
	size += expansion;
	char* tmp = new char[size];
	return tmp;
}
MyString operator+(const MyString & str1, const MyString & str2)
{
	MyString out;
	out.num_of_s = str1.num_of_s;
	out.s = out.Expand(str1.num_of_s + str2.num_of_s + 1);//分配空间
	Strcpy(out.s, str1.s);
	for (int i = out.num_of_s, j = 0; str2.s[j]; i++, j++)
	{
		out.s[i] = str2.s[j];
	}
	out.num_of_s += str2.num_of_s;
	out.s[out.num_of_s] = 0;
	return out;
}
bool operator==(const MyString & a, const MyString & b)
{
	if (a.num_of_s != b.num_of_s) return false;
	for (int i = 0; i < a.num_of_s; i++)
	{
		if (a.s[i] != b.s[i]) return false;
	}
	return true;
}

bool operator<(const MyString & a, const MyString & b)
{
	int num = a.num_of_s > b.num_of_s ? b.num_of_s : a.num_of_s;
	for (int i = 0; i < num; i++)
	{
		if (a.s[i] < b.s[i]) return true;
		if (a.s[i] > b.s[i]) return false;
	}
	if (a.num_of_s < b.num_of_s) return true;
	return false;
}

int MyString::Find(const MyString & a, int start_index)
{

	int result = -1;
	//*
	if (a.num_of_s == 0) return 0;
	for (int i = start_index; i < this->num_of_s - a.num_of_s + 1; i++)
	{
		while (i < this->num_of_s - a.num_of_s + 1 && a.s[0] != this->s[i])
			i++;
		int flag = 1;
		for (int j = 0; j < a.num_of_s && flag; j++)
		{
			if (a.s[j] != this->s[i + j]) flag = 0;
		}
		if (flag)
		{
			result = i;
			break;
		}
	}
	//*/
	return result;
}

int MyString::Findnth(const MyString & need_finded, int nth, int start_index)
{
	int result = Find(need_finded, start_index);
	for (int i = 1; i < nth && result > -1; i++)
	{
		result = Find(need_finded, result + 1);
	}
	return result;
}

MyString MyString::instead(int start_index, int end_index, const MyString & instead_str)
{
	if (end_index > num_of_s)
	{
		end_index = num_of_s;
	}
	if (start_index >= num_of_s)
	{
		return (*this + instead_str);
	}
	char* tmp = Expand(num_of_s + instead_str.num_of_s + 1);
	int j = 0;
	for (int i = 0; i < start_index; i++)
	{
		tmp[j++] = this->s[i];
	}
	for (int i = 0; i < instead_str.num_of_s; i++)
	{
		tmp[j++] = instead_str.s[i];
	}
	for (int i = end_index; i < num_of_s; i++)
	{
		tmp[j++] = this->s[i];
	}
	tmp[j] = '\0';
	return MyString(tmp);
}

MyString MyString::instead(int start_index, const MyString & instead_str)
{
	return instead(start_index, this->num_of_s, instead_str);
}



// 将英文字母转成小写
void MyString::lower_case()
{
	// TODO: 在此处添加实现代码.
	for (int i = 0; i < num_of_s; i++)
	{
		if (s[i] >= 'A' && s[i] <= 'Z')
		{
			s[i] -= 'A' - 'a';
		}
	}
}


// 返回一个从start_indx开始的长度为length的字符串
MyString MyString::substr(int start_index, int length)
{
	// TODO: 在此处添加实现代码.
	if (start_index >= num_of_s)
		return MyString("");
	if (start_index + length >= num_of_s)
		length = num_of_s - start_index + 1;
	char* result = new char[length];
	for (int i = 0; i < length; i++)
	{
		result[i] = this->s[i + start_index];
	}
	result[length] = 0;
	return MyString(result);
}

MyString MyString::substr(int start_index)
{
	if (start_index >= num_of_s)
		return MyString("");
	int length = this->num_of_s - start_index + 1;
	return this->substr(start_index, length);
}


// 将字符串转为int
int MyString::toint()
{
	//这里没有考虑溢出和不能转化为int的情况，也没有考虑有较多符号位的情况
	// TODO: 在此处添加实现代码.
	bool flag = 0;//默认为正号
	int start_index = 0;
	int result = 0;
	if (s[0] == '-') flag = 1, start_index = 1;
	if (s[0] == '+') start_index = 1;
	for (int i = start_index; i < num_of_s; i++)
	{
		result *= 10;
		result += s[i] - '0';
	}
	if (flag) result = -result;
	return result;
}

//计算某字符出现了多少次
int MyString::count(const char& in, int start_index)
{
	int result = 0;
	for (int i = start_index; i < num_of_s; i++)
		if (s[i] == in)
			result++;
	return result;
}
